home *** CD-ROM | disk | FTP | other *** search
/ Ultra Pack / UltraComputing Partner Applications.iso / SunLabs / tclTK / src / tcl7.4 / tclGet.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-07  |  5.6 KB  |  222 lines

  1. /* 
  2.  * tclGet.c --
  3.  *
  4.  *    This file contains procedures to convert strings into
  5.  *    other forms, like integers or floating-point numbers or
  6.  *    booleans, doing syntax checking along the way.
  7.  *
  8.  * Copyright (c) 1990-1993 The Regents of the University of California.
  9.  * Copyright (c) 1994-1995 Sun Microsystems, Inc.
  10.  *
  11.  * See the file "license.terms" for information on usage and redistribution
  12.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  13.  */
  14.  
  15. static char sccsid[] = "@(#) tclGet.c 1.20 95/02/14 13:14:34";
  16.  
  17. #include "tclInt.h"
  18. #include "tclPort.h"
  19.  
  20.  
  21. /*
  22.  *----------------------------------------------------------------------
  23.  *
  24.  * Tcl_GetInt --
  25.  *
  26.  *    Given a string, produce the corresponding integer value.
  27.  *
  28.  * Results:
  29.  *    The return value is normally TCL_OK;  in this case *intPtr
  30.  *    will be set to the integer value equivalent to string.  If
  31.  *    string is improperly formed then TCL_ERROR is returned and
  32.  *    an error message will be left in interp->result.
  33.  *
  34.  * Side effects:
  35.  *    None.
  36.  *
  37.  *----------------------------------------------------------------------
  38.  */
  39.  
  40. int
  41. Tcl_GetInt(interp, string, intPtr)
  42.     Tcl_Interp *interp;        /* Interpreter to use for error reporting. */
  43.     char *string;        /* String containing a (possibly signed)
  44.                  * integer in a form acceptable to strtol. */
  45.     int *intPtr;        /* Place to store converted result. */
  46. {
  47.     char *end, *p;
  48.     int i;
  49.  
  50.     /*
  51.      * Note: use strtoul instead of strtol for integer conversions
  52.      * to allow full-size unsigned numbers, but don't depend on strtoul
  53.      * to handle sign characters;  it won't in some implementations.
  54.      */
  55.  
  56.     errno = 0;
  57.     for (p = string; isspace(UCHAR(*p)); p++) {
  58.     /* Empty loop body. */
  59.     }
  60.     if (*p == '-') {
  61.     p++;
  62.     i = -strtoul(p, &end, 0);
  63.     } else if (*p == '+') {
  64.     p++;
  65.     i = strtoul(p, &end, 0);
  66.     } else {
  67.     i = strtoul(p, &end, 0);
  68.     }
  69.     if (end == p) {
  70.     badInteger:
  71.     Tcl_AppendResult(interp, "expected integer but got \"", string,
  72.         "\"", (char *) NULL);
  73.     return TCL_ERROR;
  74.     }
  75.     if (errno == ERANGE) {
  76.     interp->result = "integer value too large to represent";
  77.     Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW",
  78.         interp->result, (char *) NULL);
  79.     return TCL_ERROR;
  80.     }
  81.     while ((*end != '\0') && isspace(UCHAR(*end))) {
  82.     end++;
  83.     }
  84.     if (*end != 0) {
  85.     goto badInteger;
  86.     }
  87.     *intPtr = i;
  88.     return TCL_OK;
  89. }
  90.  
  91. /*
  92.  *----------------------------------------------------------------------
  93.  *
  94.  * Tcl_GetDouble --
  95.  *
  96.  *    Given a string, produce the corresponding double-precision
  97.  *    floating-point value.
  98.  *
  99.  * Results:
  100.  *    The return value is normally TCL_OK;  in this case *doublePtr
  101.  *    will be set to the double-precision value equivalent to string.
  102.  *    If string is improperly formed then TCL_ERROR is returned and
  103.  *    an error message will be left in interp->result.
  104.  *
  105.  * Side effects:
  106.  *    None.
  107.  *
  108.  *----------------------------------------------------------------------
  109.  */
  110.  
  111. int
  112. Tcl_GetDouble(interp, string, doublePtr)
  113.     Tcl_Interp *interp;        /* Interpreter to use for error reporting. */
  114.     char *string;        /* String containing a floating-point number
  115.                  * in a form acceptable to strtod. */
  116.     double *doublePtr;        /* Place to store converted result. */
  117. {
  118.     char *end;
  119.     double d;
  120.  
  121.     errno = 0;
  122.     d = strtod(string, &end);
  123.     if (end == string) {
  124.     badDouble:
  125.     Tcl_AppendResult(interp, "expected floating-point number but got \"",
  126.         string, "\"", (char *) NULL);
  127.     return TCL_ERROR;
  128.     }
  129.     if (errno != 0) {
  130.     TclExprFloatError(interp, d);
  131.     return TCL_ERROR;
  132.     }
  133.     while ((*end != 0) && isspace(UCHAR(*end))) {
  134.     end++;
  135.     }
  136.     if (*end != 0) {
  137.     goto badDouble;
  138.     }
  139.     *doublePtr = d;
  140.     return TCL_OK;
  141. }
  142.  
  143. /*
  144.  *----------------------------------------------------------------------
  145.  *
  146.  * Tcl_GetBoolean --
  147.  *
  148.  *    Given a string, return a 0/1 boolean value corresponding
  149.  *    to the string.
  150.  *
  151.  * Results:
  152.  *    The return value is normally TCL_OK;  in this case *boolPtr
  153.  *    will be set to the 0/1 value equivalent to string.  If
  154.  *    string is improperly formed then TCL_ERROR is returned and
  155.  *    an error message will be left in interp->result.
  156.  *
  157.  * Side effects:
  158.  *    None.
  159.  *
  160.  *----------------------------------------------------------------------
  161.  */
  162.  
  163. int
  164. Tcl_GetBoolean(interp, string, boolPtr)
  165.     Tcl_Interp *interp;        /* Interpreter to use for error reporting. */
  166.     char *string;        /* String containing a boolean number
  167.                  * specified either as 1/0 or true/false or
  168.                  * yes/no. */
  169.     int *boolPtr;        /* Place to store converted result, which
  170.                  * will be 0 or 1. */
  171. {
  172.     int i, c;
  173.     char lowerCase[10];
  174.     size_t length;
  175.  
  176.     /*
  177.      * Convert the input string to all lower-case.
  178.      */
  179.  
  180.     for (i = 0; i < 9; i++) {
  181.     c = string[i];
  182.     if (c == 0) {
  183.         break;
  184.     }
  185.     if ((c >= 'A') && (c <= 'Z')) {
  186.         c += 'a' - 'A';
  187.     }
  188.     lowerCase[i] = c;
  189.     }
  190.     lowerCase[i] = 0;
  191.  
  192.     length = strlen(lowerCase);
  193.     c = lowerCase[0];
  194.     if ((c == '0') && (lowerCase[1] == '\0')) {
  195.     *boolPtr = 0;
  196.     } else if ((c == '1') && (lowerCase[1] == '\0')) {
  197.     *boolPtr = 1;
  198.     } else if ((c == 'y') && (strncmp(lowerCase, "yes", length) == 0)) {
  199.     *boolPtr = 1;
  200.     } else if ((c == 'n') && (strncmp(lowerCase, "no", length) == 0)) {
  201.     *boolPtr = 0;
  202.     } else if ((c == 't') && (strncmp(lowerCase, "true", length) == 0)) {
  203.     *boolPtr = 1;
  204.     } else if ((c == 'f') && (strncmp(lowerCase, "false", length) == 0)) {
  205.     *boolPtr = 0;
  206.     } else if ((c == 'o') && (length >= 2)) {
  207.     if (strncmp(lowerCase, "on", length) == 0) {
  208.         *boolPtr = 1;
  209.     } else if (strncmp(lowerCase, "off", length) == 0) {
  210.         *boolPtr = 0;
  211.     } else {
  212.         goto badBoolean;
  213.     }
  214.     } else {
  215.     badBoolean:
  216.     Tcl_AppendResult(interp, "expected boolean value but got \"",
  217.         string, "\"", (char *) NULL);
  218.     return TCL_ERROR;
  219.     }
  220.     return TCL_OK;
  221. }
  222.